#include "Message_digest.h"

Message_Digest::Message_Digest(const char* filename):iss(filename,std::ifstream::binary),relleno(0){
	bit_func[0]=&F;
	bit_func[1]=&G;
	bit_func[2]=&H;
	bit_func[3]=&I;
	idx_func[0]=&sub_bloque_para_F;
	idx_func[1]=&sub_bloque_para_G;
	idx_func[2]=&sub_bloque_para_H;
	idx_func[3]=&sub_bloque_para_I;
	memset(buffer,(char)0,BLOCK_SIZE);
}
char Message_Digest::set_to_char(int& idx,std::string& buffer){
	idx=BITS_IN_BYTE;
	int number=0;
	for(int i=0;i<BITS_IN_BYTE;++i)
		number+=(int) buffer[i]*pow(BASE,i);
	buffer.assign(BITS_IN_BYTE,NULL_BYTE);
	return (char) number;
}

void Message_Digest::ejecutar_operacion(size_t idx,size_t func_idx){
	unsigned t=floor(pow(BASE,EXP)*fabs(sin(idx+1)));
	unsigned res_parcial=(*(bit_func[func_idx]))(arg_val[1],arg_val[2],arg_val[3]);
	unsigned idx_bloque= (*idx_func[func_idx])(idx);
	unsigned char sub_bloque[SUB_BLOCK_SIZE];
	strncpy ((char*)sub_bloque,(char*)&buffer[idx_bloque*SUB_BLOCK_SIZE],SUB_BLOCK_SIZE);
//	std::cout<<sub_bloque<<std::endl;
/*	std::string str;
	boost::to_string(block, str);
	std::string sub_bloque(str.substr(idx_bloque*SUB_BLOCK_BIT_SIZE,SUB_BLOCK_BIT_SIZE));*/
	unsigned M(convertir_a_num(sub_bloque));
	arg_val[0]=arg_val[1] + CIRCULAR_SHIFT((arg_val[0])+res_parcial + M + t,s[idx]);
}
void Message_Digest::procesar_bloque(){
	size_t idx=0;
	for (size_t func_idx=0;func_idx<NUM_FUNC;++func_idx){
//		std::cout<<"Round "<<func_idx<<std::endl;
		for(size_t j=0;j< NUM_SUB_BLOCKS;++j){
			ejecutar_operacion(idx,func_idx);
			arg_val.rotar();
			++idx;
		}
	}
	FINAL_VALUES+=arg_val;
}
std::string Message_Digest::obtener_resumen(){
	int block_count=1;
	do{
		iss.read((char*)buffer,BLOCK_SIZE);
		relleno=BLOCK_SIZE - iss.gcount();
		if (relleno !=0){
			buffer[iss.gcount()]=(unsigned char)PRIMER_BYTE_RELLENO;
		}
		procesar_bloque();
		++block_count;
	}while (!iss.eof());
	return (std::string)FINAL_VALUES;
}
Message_Digest::~Message_Digest(){
		iss.close();
}
